package cn.iocoder.yudao.im.service.Impl;

import cn.iocoder.yudao.im.domain.NoticeImGroupMember;
import cn.iocoder.yudao.im.mapper.NoticeImGroupMemberMapper;
import cn.iocoder.yudao.im.service.NoticeImGroupMemberService;
import cn.iocoder.yudao.im.util.DateTimeUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 群成员 服务实现类
 * </p>
 *
 * @author ZCC
 * @since 2024-07-02
 */
@Service
public class NoticeImGroupMemberServiceImpl extends ServiceImpl<NoticeImGroupMemberMapper, NoticeImGroupMember> implements NoticeImGroupMemberService {
    @CacheEvict(cacheNames = "groupId", key = "#member.getGroupId()")
    @Override
    public boolean save(NoticeImGroupMember member) {
        return super.save(member);
    }

    @CacheEvict(cacheNames = "groupId", key = "#groupId")
    @Override
    public boolean saveOrUpdateBatch(Long groupId, List<NoticeImGroupMember> members) {
        return super.saveOrUpdateBatch(members);
    }


    @Override
    public NoticeImGroupMember findByGroupAndUserId(Long groupId, Long userId) {
        QueryWrapper<NoticeImGroupMember> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(NoticeImGroupMember::getGroupId, groupId)
                .eq(NoticeImGroupMember::getUserId, userId);
        return this.getOne(wrapper);
    }

    @Override
    public List<NoticeImGroupMember> findByUserId(Long userId) {
        LambdaQueryWrapper<NoticeImGroupMember> memberWrapper = Wrappers.lambdaQuery();
        memberWrapper.eq(NoticeImGroupMember::getUserId, userId)
                .eq(NoticeImGroupMember::getQuit, 0);
        return this.list(memberWrapper);
    }

    @Override
    public List<NoticeImGroupMember> findQuitInMonth(Long userId) {
        Date monthTime = DateTimeUtils.addMonths(new Date(), -1);
        LambdaQueryWrapper<NoticeImGroupMember> memberWrapper = Wrappers.lambdaQuery();
        memberWrapper.eq(NoticeImGroupMember::getUserId, userId)
                .eq(NoticeImGroupMember::getQuit, true)
                .ge(NoticeImGroupMember::getQuitTime, monthTime);
        return this.list(memberWrapper);
    }

    @Override
    public List<NoticeImGroupMember> findByGroupId(Long groupId) {
        LambdaQueryWrapper<NoticeImGroupMember> memberWrapper = Wrappers.lambdaQuery();
        memberWrapper.eq(NoticeImGroupMember::getGroupId, groupId);
        return this.list(memberWrapper);
    }

    @Cacheable(cacheNames = "groupId", key = "#groupId")
    @Override
    public List<Long> findUserIdsByGroupId(Long groupId) {
        LambdaQueryWrapper<NoticeImGroupMember> memberWrapper = Wrappers.lambdaQuery();
        memberWrapper.eq(NoticeImGroupMember::getGroupId, groupId)
                .eq(NoticeImGroupMember::getQuit, false)
                .select(NoticeImGroupMember::getUserId);
        List<NoticeImGroupMember> members = this.list(memberWrapper);
        return members.stream().map(NoticeImGroupMember::getUserId).collect(Collectors.toList());
    }

    @CacheEvict(cacheNames = "groupId", key = "#groupId")
    @Override
    public void removeByGroupId(Long groupId) {
        LambdaUpdateWrapper<NoticeImGroupMember> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(NoticeImGroupMember::getGroupId, groupId)
                .set(NoticeImGroupMember::getQuit, true)
                .set(NoticeImGroupMember::getQuitTime, new Date());
        this.update(wrapper);
    }

    @CacheEvict(cacheNames = "groupId", key = "#groupId")
    @Override
    public void removeByGroupAndUserId(Long groupId, Long userId) {
        LambdaUpdateWrapper<NoticeImGroupMember> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(NoticeImGroupMember::getGroupId, groupId)
                .eq(NoticeImGroupMember::getUserId, userId)
                .set(NoticeImGroupMember::getQuit, true)
                .set(NoticeImGroupMember::getQuitTime, new Date());
        this.update(wrapper);
    }
}
